home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Systemmonitors / Snoopy / Sources / main.asm next >
Assembly Source File  |  1996-09-26  |  43KB  |  1,658 lines

  1.  
  2.         incpath    include:
  3.         maclib    sm.mac
  4.         macfile    macro.i
  5.         macfile    snoopy.i
  6.         macfile    macros/main
  7.         macfile    extern/parse
  8.         macfile    extern/misc
  9.         macfile    macros/startup
  10.         macfile    extern/patch
  11.  
  12.         DETACHSTARTUPARGS <argTemplate>,<argFirst>,maincode,4096
  13.  
  14. maincode    bsr    Setup
  15.         tst    d0
  16.         bne    .FAIL
  17.  
  18. ;--------------    if the user only wants to quit, don't show anything
  19.         tst.l    (argQuit)
  20.         bne    .QUITONLY
  21.  
  22. ;--------------    give out initial welcome to the user
  23.         move.l    (currentInstance),(outputArgs)
  24.         SHOWMSG    hello
  25.  
  26. ;--------------    main loop ! Wait for signals to arrive, and process them 
  27. .MainLoop    move.l    (waitsignals),d0
  28.         CALL    Wait,<(execBase).w>
  29.         move.l    d0,(signals)
  30.  
  31. ;--------------    CTRL+C terminates the program
  32.         BRBS    #SIGBREAKB_CTRL_C,d0,.DONE
  33.  
  34. ;--------------    if we got a message, then answer it
  35.         move.l    d0,d1
  36.         and.l    (answersignal),d1
  37.         tst.l    d1
  38.         beq.b    .NoMessage
  39.         bsr    HandleReply
  40.         bra.b    .MainLoop
  41. .NoMessage
  42. ;--------------    CTRL+D disables output
  43.         BRBC.B    #SIGBREAKB_CTRL_D,d0,.DisableOutput
  44.         tst.b    (outputactive)
  45.         beq.b    .MainLoop
  46.         move.b    #FALSE,(outputactive)
  47.         SHOWMSG    disableout
  48.         bra    .MainLoop
  49. .DisableOutput
  50. ;--------------    CTRL+E disables output
  51.         BRBC.B    #SIGBREAKB_CTRL_E,d0,.EnableOutput
  52.         tst.b    (outputactive)
  53.         bne.b    .MainLoop
  54.         move.b    #TRUE,(outputactive)
  55.         SHOWMSG    enableout
  56.         bra    .MainLoop
  57. .EnableOutput
  58. ;--------------    CTRL+F toggles the task info feature
  59.         BRBC.B    #SIGBREAKB_CTRL_F,d0,.ToggleTI
  60.         tst.l    (argTaskInfo)
  61.         bne.b    .TI_Disabled
  62.         move.l    #TRUE,(argTaskInfo)
  63.         SHOWMSG    TIenabled
  64.         bra    .MainLoop
  65. .TI_Disabled    SHOWMSG    TIdisabled
  66.         clr.l    (argTaskInfo)
  67. .ToggleTI
  68.         bra    .MainLoop
  69.  
  70. ;--------------    sorry, calls still active
  71. .CALLSACTIVE    lea    (activeCallsErr,pc),a0
  72.         move.l    (ActiveCalls),(outputArgs)
  73.         jsr    ShowErrorMessage
  74.         bra    .MainLoop
  75.  
  76. .DONE        tst.l    (ActiveCalls)
  77.         bne.b    .CALLSACTIVE
  78.         bsr    RemoveFunctions    ; remove all functions
  79.         tst.w    d0
  80.         beq    .MainLoop
  81. .QUITONLY    bsr    Cleanup
  82.         moveq    #RETURN_OK,d0
  83.         rts
  84.  
  85. .FAIL        bsr    RemoveFunctions ; MUST succeed, otherwise we're really in trouble
  86.         bsr    Cleanup
  87.         moveq    #RETURN_ERROR,d0
  88.         rts
  89.  
  90. ***********************************************************************************
  91. ;--------------    
  92.         ENTRY    Setup,d1-d7/a0-a6
  93.         clr.l    (ActiveCalls)        
  94.  
  95. ;--------------    empty all lists used
  96.         prepare    hides
  97.         prepare    shows
  98.         prepare    bases
  99.         prepare    watches
  100.         prepare    deviceBases
  101.         prepare    aliases
  102.         prepare    defines
  103.         prepare    resources
  104.         move.b    #TRUE,(outputactive)
  105.  
  106. ;--------------    open librarys needed
  107.         openlib    int
  108.         openlib    icon
  109.         bsr    ReadWBArgs
  110.  
  111. ;--------------    perhaps we only need to remove any running Snoopys ?! 
  112.         tst.l    (argQuit)
  113.         beq.b    .DONTQUIT
  114.         bsr    QuitSnoopyInstances
  115.         moveq    #TRUE,d0
  116.         bra    Setup_done
  117. .DONTQUIT
  118. ;--------------    build taskname to be removeable 
  119.         bsr    BuildSnoopysTaskname
  120.  
  121. ;--------------    try to open script file
  122.         move.l    (argScript),d0
  123.         bne.b    .CallParser
  124.         move.l    #defaultScript,d0
  125. .CallParser    movea.l    d0,a0
  126.         jsr    ParseScriptFile
  127.         tst    d0
  128.         bne    .NODOSBASE ; this looks strange but it works just fine
  129.  
  130. ;--------------    defines and aliases are not needed any longer, so they can be
  131. ;--------------    freed immediately 
  132.         remlist    defines,sdef_SIZEOF
  133.         remlist    aliases,salias_SIZEOF
  134.  
  135. ;--------------    try to find SegTracker(tm)
  136.         clr.l    (SegTracker)
  137.         lea    (SegTrackerName,pc),a1
  138.         CALL    FindSemaphore,<(execBase).w>
  139.         tst.l    d0
  140.         beq.b    .NOSEMAPHORE
  141.         movea.l    d0,a0
  142.         move.b    #TRUE,(SegTrackerOn)
  143.         move.l    (segs_Find,a0),(SegTracker)
  144. .NOSEMAPHORE
  145. ;--------------    create msgport
  146.         CALL    CreateMsgPort,<(execBase).w>
  147.         move.l    d0,(myport)
  148.         beq    .NOMSGPORT
  149.         move.l    (ThisTask,a6),(thistask)
  150.         movea.l    d0,a1
  151.         move.l    #currentPortName,(LN_NAME,a1)
  152.         moveq    #0,d0
  153.         move.b    (MP_SIGBIT,a1),d0
  154.         moveq    #1,d1
  155.         lsl.l    d0,d1
  156.         move.l    d1,(answersignal)
  157.         or.l    #MASK_SIGNALS,d1
  158.         move.l    d1,(waitsignals)
  159.         CALL    AddPort
  160.  
  161. ;--------------    open CON: window
  162.         move.l    #windowName,d1
  163.         tst.b    (outputMemory)
  164.         beq.b    .NOOUTPUTKEYWRD
  165.         move.l    #outputMemory,d1
  166. .NOOUTPUTKEYWRD    tst.l    (argOutput)
  167.         beq.b    .DefaultWindow
  168.         move.l    (argOutput),d1
  169. .DefaultWindow    move.l    #MODE_READWRITE,d2
  170.         CALL    Open,<(dosBase)>
  171.         move.l    d0,(window)
  172.         beq.b    .NOWINDOW
  173.         jsr    SetCmdlineSHOWs
  174.  
  175. ;--------------    patch functions
  176.         bsr    PatchFunctions
  177.         tst.w    d0
  178.         beq.b    .NODOSBASE
  179.  
  180. ;--------------    set my priority (if applicable)
  181.         move.l    (priority),d0
  182.         tst.l    (argPri)
  183.         beq.b    .NOPRICMD
  184.         movea.l    (argPri),a0
  185.         move.l    (a0),d0
  186. .NOPRICMD    movea.l    (execBase).w,a6
  187.         movea.l    (ThisTask,a6),a1
  188.         CALL    SetTaskPri
  189.  
  190.         moveq    #RETURN_OK,d0
  191.         bra.b    Setup_done
  192.  
  193. .NOWINDOW    lea    (nowindowErr,pc),a0
  194.         bra.b    .FAIL        
  195. .NOMSGPORT    lea    (nomsgportErr,pc),a0
  196. .FAIL        jsr    ShowErrorMessage
  197. .NODOSBASE    moveq    #RETURN_ERROR,d0
  198.         DONE    Setup
  199.  
  200. ***********************************************************************************
  201. ;--------------    
  202.         ENTRY    Cleanup,d0-d7/a0-a6
  203.  
  204.         bsr    RemoveDeviceBases
  205.         bsr    RemoveLibraryBases
  206.  
  207. ;--------------    close window
  208.         move.l    (window),d1
  209.         beq.b    .NoWindow
  210.         CALL    Close,<(dosBase)>
  211. .NoWindow
  212. ;--------------    remove msgport
  213.         move.l    (myport),d0
  214.         beq.b    .NoMsgPort
  215.         movea.l    d0,a1
  216.         CALL    RemPort,<(execBase).w>
  217.         bsr    RemoveAllMessages
  218.         movea.l    (myport),a0
  219.         CALL    DeleteMsgPort
  220. .NoMsgPort
  221. ;--------------    close CLI arguments
  222.         move.l    (argRdargs),d1
  223.         beq.b    .NoRdArgs
  224.         CALL    FreeArgs,<(dosBase)>
  225. .NoRdArgs
  226. ;--------------    close librarys
  227.         closelb    int
  228.         closelb    icon
  229.  
  230. ;--------------    remove structures
  231.         remlist    defines,sdef_SIZEOF
  232.         remlist    aliases,salias_SIZEOF
  233.         remlist    bases,sbase_SIZEOF
  234.         remlist    resources,sbase_SIZEOF
  235.         remlist    hides,stask_SIZEOF
  236.         remlist    shows,stask_SIZEOF
  237.         remlist    watches,spatch_SIZEOF
  238.         remlist    deviceBases,sdevbase_SIZEOF
  239.         DONE    Cleanup
  240.  
  241. ***********************************************************************************
  242. ;--------------    remove all remaining messages from the port (so that we can be sure
  243. ;--------------    we have not lost any memory
  244. ;--------------    
  245.         ENTRY    RemoveAllMessages,d0-d7/a0-a6
  246.  
  247. ;--------------    free message memory
  248.         movea.l    (execBase).w,a6
  249. .LOOP        movea.l    (myport),a0
  250.         CALL    GetMsg
  251.         tst.l    d0
  252.         beq.b    .DONE
  253.         movea.l    d0,a1
  254.         move.l    #smsg_SIZEOF,d0
  255.         CALL    FreeMem
  256.         bra.b    .LOOP
  257. .DONE        DONE    RemoveAllMessages
  258.  
  259. ***********************************************************************************
  260. ;--------------    remove all library bases
  261.  
  262.         ENTRY    RemoveLibraryBases,d0-d7/a0-a6
  263.         lea    (bases),a5
  264.         movea.l    (LH_HEAD,a5),a5
  265.         movea.l    (execBase).w,a6
  266. .BASELOOP    tst.l    (LN_SUCC,a5)    ; a5 = current node
  267.         beq.b    .BASEDONE
  268.         move.l    (sbase_Library,a5),d0
  269.         beq.b    .NEXTBASE
  270.         clr.l    (sbase_Library,a5)
  271.         movea.l    d0,a1
  272.         CALL    CloseLibrary
  273. .NEXTBASE    movea.l    (LN_SUCC,a5),a5
  274.         bra.b    .BASELOOP
  275. .BASEDONE    DONE    RemoveLibraryBases
  276.  
  277. ***********************************************************************************
  278. ;--------------    remove all device bases
  279.  
  280.         ENTRY    RemoveDeviceBases,d0-d7/a0-a6
  281.         lea    (deviceBases),a5
  282.         movea.l    (LH_HEAD,a5),a5
  283. .BASELOOP2    tst.l    (LN_SUCC,a5)    ; a5 = current node
  284.         beq.b    .BASEDONE2
  285.  
  286. ;--------------    remove message port
  287.         ;move.l    (sdevbase_MsgPort,a5),d0
  288.         ;beq.b    .NOMSGPORT
  289.         ;movea.l    d0,a0
  290.         ;CALL    DeleteMsgPort,<(execBase).w>
  291. .NOMSGPORT
  292. ;--------------    remove device bases
  293.         move.l    (sdevbase_Device,a5),d0
  294.         beq.b    .NEXTBASE2
  295.         clr.l    (sdevbase_Device,a5)
  296.         movea.l    d0,a1
  297.         CALL    Forbid,<(execBase).w>
  298.         subq.w    #1,(LIB_OPENCNT,a1)
  299.         move.b    (LIB_FLAGS,a1),d0
  300.         bset    #LIBB_CHANGED,d0
  301.         move.b    d0,(LIB_FLAGS,a1)
  302.         CALL    SumLibrary
  303.         CALL    Permit
  304.  
  305. ;--------------    free all patches for this device)
  306. .NEXTBASE2    lea    (sdevbase_Patches,a5),a0
  307.         move.l    #spatch_SIZEOF,d0
  308.         jsr    RemoveList
  309.         movea.l    (LN_SUCC,a5),a5
  310.         bra.b    .BASELOOP2
  311. .BASEDONE2    DONE    RemoveDeviceBases
  312.  
  313. ***********************************************************************************
  314. ;--------------    build a unique taskname for the current copy of Snoopy [this is
  315. ;--------------    required even if option QUIT was given]
  316. ;--------------    
  317.         ENTRY    BuildSnoopysTaskname,d0-d7/a0-a6
  318.         moveq    #0,d7    ; used to count the number of Snoopys installed
  319.  
  320. ;--------------    examine waiting tasks
  321.         CALL    Forbid,<(execBase).w>    ; stop multitasking
  322.         lea    (TaskWait,a6),a4
  323.         movea.l    (LH_HEAD,a4),a4
  324. .LOOP1        tst.l    (LN_SUCC,a4)
  325.         beq.b    .DONE1
  326.         bsr.b    .FINDSNOOPY
  327.         movea.l    (LN_SUCC,a4),a4
  328.         bra.b    .LOOP1
  329.  
  330. ;--------------    examine ready tasks
  331. .DONE1        lea    (TaskReady,a6),a4
  332.         movea.l    (LH_HEAD,a4),a4
  333. .LOOP2        tst.l    (LN_SUCC,a4)
  334.         beq.b    .DONE2
  335.         bsr.b    .FINDSNOOPY
  336.         movea.l    (LN_SUCC,a4),a4
  337.         bra.b    .LOOP2
  338. .DONE2        CALL    Permit,<(execBase).w>    ; reallow multitasking
  339.         addq.w    #1,d7    ; "addq.l" would be too pretentious, really....  ;-)
  340.         move.l    d7,(currentInstance)
  341.  
  342. ;--------------    build new taskname and portname
  343.         lea    (outputArgs),a1        
  344.         move.l    d7,(a1)
  345.         lea    (taskNameFormat,pc),a0
  346.         lea    (currentTaskName),a2
  347.         jsr    SPrintf
  348.         lea    (taskPortFormat,pc),a0
  349.         lea    (currentPortName),a2
  350.         jsr    SPrintf
  351.  
  352. ;--------------    install taskname
  353.         movea.l    (ThisTask,a6),a0
  354.         move.l    #currentTaskName,(LN_NAME,a0)
  355.         bra.b    BuildSnoopysTaskname_done
  356.  
  357. ;--------------    trys to find out the name for a task
  358. .FINDSNOOPY    move.l    (LN_NAME,a4),d0
  359.         beq.b    .SKIP
  360.         movea.l    d0,a0
  361.         lea    (taskNameFormat,pc),a1
  362.         moveq    #taskNameFormat_SIZEOF-1,d0
  363. .STRCMP        move.b    (a0)+,d1
  364.         cmp.b    (a1)+,d1
  365.         bne.b    .SKIP
  366.         dbra    d0,.STRCMP
  367.         moveq    #STVFORMAT_DEC,d0
  368.         jsr    StringToValue
  369.         cmp.w    d7,d0
  370.         bls.b    .SKIP
  371.         move.w    d0,d7
  372. .SKIP        rts
  373.  
  374.         DONE    BuildSnoopysTaskname
  375.  
  376. ***********************************************************************************
  377. ;--------------    yeah, we got ourselfs a message; now show it and go home
  378. ;--------------    
  379.         ENTRY    HandleReply,d0-d7/a0-a6
  380.  
  381. .LOOP        movea.l    (myport),a0
  382.         CALL    GetMsg,<(execBase).w>
  383.         move.l    d0,(message)
  384.         tst.l    d0
  385.         beq    HandleReply_done
  386.         movea.l    d0,a5            ; a5=message
  387.  
  388. ;--------------    output handling is different if its a device message
  389.         move.w    (smsg_Type,a5),d0
  390.         BRBS    #MSGTYPEB_DEBUG,d0,.HANDLEDEBUG
  391.         BRBS    #MSGTYPEB_DEVICE,d0,.HANDLEDEVICE
  392.  
  393. ;--------------    now we have the message and its data, so lets go for it !
  394.         tst.b    (outputactive)
  395.         beq    .SkipOutput
  396.  
  397. ;--------------    if the task is hidden, skip output
  398.         movea.l    (smsg_Task,a5),a0
  399.         bsr    IsTaskHidden
  400.         tst    d0
  401.         bne.b    .SkipOutput
  402.  
  403. ;--------------    handle 
  404.         movea.l    (smsg_Info,a5),a0
  405.         move.l    (spatch_Flags,a0),d0
  406.         BRBC.B    #SINFOB_SKIPSIMILAR,d0,.SKIPSIMILAR
  407.         move.l    a0,d0
  408.         cmp.l    (lastMessage),d0
  409.         beq.b    .SkipOutput
  410.         move.l    d0,(lastMessage)
  411. .SKIPSIMILAR    
  412. ;--------------    show extended task info if applicable
  413.         tst.l    (argTaskInfo)
  414.         beq.b    .NoTaskInfo
  415.         movea.l    (smsg_Task,a5),a0
  416.         bsr    ShowTaskInfo
  417. .NoTaskInfo
  418. ;--------------    if SEGTRACKER is there, show segment of pc
  419.         tst.l    (SegTracker)
  420.         beq.b    .NoSegTracker
  421.         movea.l    (smsg_RegsBeforeCall+sregs_I7,a5),a0    ; a0=address to show
  422.         movea.l    (smsg_Info,a5),a1            ; a1=PatchInfo
  423.         move.l    (spatch_Flags,a1),d0
  424.         BRBS.B    #SINFOB_NOSEGTRACKER,d0,.NoSegTracker
  425.         bsr    ShowSegTracker
  426. .NoSegTracker
  427. ;--------------    prepare output data
  428. .SHOWMESSAGE    movea.l    (smsg_Info,a5),a4    ; a4=PatchInfo
  429.         lea    (spatch_Arguments,a4),a1    ; a1 = current position in argument template
  430.         moveq    #TRUE,d0
  431.         bsr    SetupOutputData
  432.  
  433. ;--------------    send message
  434.         lea.l    (spatch_Template,a4),a0
  435.         jsr    ShowMessage
  436.         move.l    (window),d1
  437.         CALL    Flush,<(dosBase)>
  438.         bsr.b    .NEWLINE
  439.  
  440. ;--------------    free message memory
  441. .SkipOutput    movea.l    (message),a1
  442.         move.l    #smsg_SIZEOF,d0
  443.         CALL    FreeMem,<(execBase).w>
  444.         bra    .LOOP
  445.  
  446. .NEWLINE    move.l    (window),d1
  447.         move.l    #newlineMsg,d2
  448.         moveq    #1,d3
  449.         CALL    Write,<(dosBase)>
  450.         move.l    (window),d1
  451.         CALL    Flush
  452.         rts
  453.  
  454. ;---------------------------------------------------------------------------
  455. ;--------------    this is were we deal with USER-DEBUG messages
  456. ;--------------    
  457.  
  458. ;--------------    skip if output deactivated
  459. .HANDLEDEBUG    tst.b    (outputactive)
  460.         beq    .LISTDONE
  461.  
  462. ;--------------    if the task is hidden, skip output
  463.         movea.l    (message),a5
  464.         movea.l    (sumsg_Task,a5),a0
  465.         bsr    IsTaskHidden
  466.         tst    d0
  467.         bne    .LISTDONE
  468.  
  469. ;--------------    show extended task info if applicable
  470.         tst.l    (argTaskInfo)
  471.         beq.b    .NoDebugTaskInfo
  472.         movea.l    (sumsg_Task,a5),a0
  473.         bsr    ShowTaskInfo
  474. .NoDebugTaskInfo
  475. ;--------------    if SEGTRACKER is there, show segment of pc
  476.         tst.l    (SegTracker)
  477.         beq.b    .NoDebugSegTracker
  478.         movea.l    (sumsg_RegsBeforeCall+sregs_I7,a5),a0    ; a0=address to show
  479. ;--------------    SKIPSEGTRACKER not supported for Debug calls
  480.         bsr    ShowSegTracker
  481. .NoDebugSegTracker
  482.         move.l    (sumsg_Template,a5),d0
  483.         beq    .DebugUseDefaultTemplate
  484.         movea.l    d0,a4
  485.         lea    (4,a4),a1    ; a1 = current position in argument template
  486.         bsr    SetupOutputData
  487.         moveq    #FALSE,d0
  488.         bsr    SetupOutputData
  489.  
  490. ;--------------    send message
  491.         movea.l    (sumsg_Template,a5),a0
  492.         movea.l    (a0),a0
  493.         jsr    ShowMessage
  494.         move.l    (window),d1
  495.         CALL    Flush,<(dosBase)>
  496.         bsr    .NEWLINE
  497.         bra    .LISTDONE
  498.  
  499. ;--------------    no explicit user template, use default
  500. .DebugUseDefaultTemplate
  501.         lea    (outputArgs),a0
  502.         lea    (sumsg_RegsBeforeCall,a5),a1
  503.         SAVEDEBUGREGISTERS
  504.         lea    (sumsg_RegsAfterCall,a5),a1
  505.         SAVEDEBUGREGISTERS
  506.         lea    (DebugDefTempMsg,pc),a0
  507.         jsr    ShowMessage
  508.         move.l    (window),d1
  509.         CALL    Flush,<(dosBase)>
  510.         bra    .LISTDONE
  511.  
  512. ;---------------------------------------------------------------------------
  513. ;--------------    the rest of this function deals with the device messages
  514. ;--------------    
  515.  
  516. ;--------------    skip if output deactivated
  517. .HANDLEDEVICE    tst.b    (outputactive)
  518.         beq    .LISTDONE
  519.  
  520. ;--------------    if the task is hidden, skip output
  521.         movea.l    (message),a4
  522.         movea.l    (sdmsg_Task,a4),a0
  523.         bsr    IsTaskHidden
  524.         tst    d0
  525.         bne    .LISTDONE
  526.  
  527. ;--------------    lets see if we understand this message
  528.         movea.l    (sdmsg_DeviceBase,a4),a5
  529.         lea    (sdevbase_Patches,a5),a5
  530.         movea.l    (LH_HEAD,a5),a5            ; a5=current patch
  531.         move.w    (sdmsg_SIZEOF+IO_COMMAND,a4),d0    ; d0=current command
  532. .LISTLOOP    tst.l    (LN_SUCC,a5)
  533.         beq.b    .LISTDONE
  534.  
  535. ;--------------    offset=-1 -> show always
  536.         cmpi.w    #-1,(spatch_Offset,a5)
  537.         beq.b    .SHOWALWAYS
  538.         cmp.w    (spatch_Offset,a5),d0
  539.         bne.b    .SKIPLIST
  540.  
  541. ;--------------    show only if the appropriate bits are set
  542. .SHOWALWAYS    move.l    (spatch_Flags,a5),d0
  543.         move.w    (smsg_Type,a4),d1
  544.         BRBS.B    #MSGTYPEB_BEGINIO,d1,.ITSBEGINIO
  545.         BRBC.B    #SINFOB_ABORTIO,d0,.SKIPLIST
  546.         bra.b    .ITSOK
  547. .ITSBEGINIO    BRBC.B    #SINFOB_BEGINIO,d0,.SKIPLIST
  548. .ITSOK
  549. ;--------------    show extended task info if applicable
  550.         tst.l    (argTaskInfo)
  551.         beq.b    .NoDTaskInfo
  552.         movea.l    (sdmsg_Task,a4),a0
  553.         bsr    ShowTaskInfo
  554. ;--------------    if SEGTRACKER is there, show segment of pc
  555. .NoDTaskInfo    tst.l    (SegTracker)
  556.         beq.b    .NoDSegTracker
  557.         movea.l    (sdmsg_PC,a4),a0            ; a0=address to show
  558.         move.l    (spatch_Flags,a5),d0
  559.         BRBS.B    #SINFOB_NOSEGTRACKER,d0,.NoDSegTracker
  560.         bsr    ShowSegTracker
  561. .NoDSegTracker    movea.l    a5,a0
  562.         bsr.b    ShowDeviceMessage
  563.         bsr    .NEWLINE
  564.         bra.b    .LISTDONE
  565. .SKIPLIST    movea.l    (LN_SUCC,a5),a5
  566.         bra.b    .LISTLOOP
  567.  
  568. ;--------------    free message memory and return to main loop
  569. .LISTDONE    movea.l    (message),a1
  570.         moveq    #0,d0
  571.         move.w    (MN_LENGTH,a1),d0
  572.         CALL    FreeMem,<(execBase).w>
  573.         bra    .LOOP
  574.  
  575.         DONE    HandleReply
  576.  
  577. ***********************************************************************************
  578. ;--------------    
  579. ;--------------    => a0: (struct SnoopyPatch *)
  580. ;--------------    
  581.         ENTRY    ShowDeviceMessage,d0-d7/a0-a6
  582.  
  583. ;--------------    prepare output data
  584.         movea.l    (message),a5
  585.         movea.l    a0,a4    ; a4 = patch 
  586.         bsr    SetupDeviceOutputData
  587.  
  588. ;--------------    send message
  589.         lea.l    (spatch_Template,a4),a0
  590.         jsr    ShowMessage
  591.         move.l    (window),d1
  592.         CALL    Flush,<(dosBase)>
  593.         DONE    ShowDeviceMessage
  594.  
  595. ***********************************************************************************
  596. ;--------------    
  597. ;--------------    -> a4: Patch Info
  598. ;--------------       a5: Register Data
  599.  
  600.         ENTRY    SetupDeviceOutputData,d0-d7/a0-a6
  601.         lea    (outputArgs),a0    ; a0 = current output offset
  602.         lea    (spatch_Arguments,a4),a1    ; a1 = current position in argument template
  603.         movea.l    (message),a3
  604.         lea    (sdmsg_SIZEOF,a3),a2
  605.  
  606. ;--------------    done ? then lets go !
  607. .LOOP        move.w    (sarg_Opcode,a1),d0
  608.         cmpi.w    #REG_DONE,d0
  609.         beq.b    SetupDeviceOutputData_done
  610.  
  611. ;--------------    if REGB_INDIRECT is given, I display internal data!!!!!!!!!
  612.         BRBS    #REGB_INDIRECT,d0,.SHOWINTERNAL
  613.         BRBS.B    #REGB_BYTE,d0,.SETBYTE
  614.         BRBS.B    #REGB_WORD,d0,.SETWORD
  615. .SETLONG    move.l    (sarg_Offset,a1),d0
  616.         move.l    (a2,d0.l),(a0)+
  617.         bra.b    .NEXT
  618. .SETWORD    move.l    (sarg_Offset,a1),d0
  619.         move.w    (a2,d0.l),(a0)+
  620.         bra.b    .NEXT
  621. .SETBYTE    move.l    (sarg_Offset,a1),d0
  622.         move.b    (a2,d0.l),d0
  623.         ext.w    d0
  624.         move.w    d0,(a0)+
  625. .NEXT        lea    (sarg_SIZEOF,a1),a1
  626.         bra.b    .LOOP
  627.  
  628. ;--------------    
  629. .SHOWINTERNAL    andi.w    #%111,d0    ; get bit number
  630.         tst.b    d0
  631.         beq.b    .SHOWCALLTYPE
  632.  
  633. ;--------------    NOT SUPPORTED!
  634.         bra.b    .NEXT
  635.  
  636. .SHOWCALLTYPE    move.l    #abortIOMsg,d0
  637.         move.w    (smsg_Type,a3),d1
  638.         BRBC.B    #MSGTYPEB_BEGINIO,d1,.ISABORTIO
  639.         move.l    #beginIOMsg,d0
  640. .ISABORTIO    move.l    d0,(a0)+
  641.         bra.b    .NEXT
  642.         
  643.         DONE    SetupDeviceOutputData
  644.  
  645. ***********************************************************************************
  646. ;--------------    checks if the current task is hidden, returns TRUE if so
  647.         ENTRY    IsTaskHidden,d1-d7/a0-a6
  648.  
  649. ;--------------    a3 = task pointer
  650.         movea.l    a0,a3
  651.  
  652. ;--------------    find taskname to a4
  653.         movea.l    a0,a1
  654.         cmpi.b    #NT_PROCESS,(LN_TYPE,a0)
  655.         bne.b    .DEFAULT
  656.         tst.l    (pr_TaskNum,a0)
  657.         beq.b    .DEFAULT
  658.         move.l    (pr_CLI,a0),d0
  659.         lsl.l    #2,d0
  660.         movea.l    d0,a0
  661.         move.l    (cli_CommandName,a0),d0
  662.         lsl.l    #2,d0
  663.         addq.l    #1,d0
  664.         movea.l    d0,a4
  665.         bra.b    .DONE
  666. .DEFAULT    movea.l    (LN_NAME,a0),a4
  667. .DONE    
  668. ;--------------    handle SHOWs
  669.         tst.b    (showsactive)
  670.         beq.b    .NoSHOWs
  671.         lea    (shows),a5
  672.         bsr.b    CheckIfIsInList
  673.         not.l    d0
  674.         bra.b    IsTaskHidden_done
  675. .NoSHOWs
  676. ;--------------    handle HIDEs
  677.         lea    (hides),a5
  678.         bsr.b    CheckIfIsInList
  679.         DONE    IsTaskHidden
  680.  
  681. ***********************************************************************************
  682. ;--------------    checks if an entry can be found in a list
  683. ;--------------    
  684. ;-------------- -> a5: struct List *HEAD
  685. ;--------------       a4: STRPTR name
  686. ;--------------       a3: APTR task
  687. ;--------------    <- d0: TRUE=Member of this list, FALSE otherwise
  688. ;--------------    
  689.         ENTRY    CheckIfIsInList,d1-d7/a0-a6
  690.         cmpa.l    #0,a4
  691.         beq.b    .NotInList
  692.         movea.l    (LH_HEAD,a5),a5
  693. .LOOP        tst.l    (LN_SUCC,a5)    ; a5 = current node
  694.         beq.b    .NotInList
  695.         movea.l    a4,a0
  696.         move.l    (stask_Pointer,a5),d0
  697.         beq.b    .CHECKNAME
  698.         cmpa.l    d0,a3
  699.         beq.b    .InList
  700. .CHECKNAME    lea    (stask_Name,a5),a1
  701.  
  702. ;--------------    NEW: exact matching enabled
  703.         tst.l    (argMatch)
  704.         bne.b    .STRCMP
  705.  
  706. .STRICMP    move.b    (a1)+,d0
  707.         beq.b    .InList
  708.         move.b    (a0)+,d1
  709.         UCASE    d0
  710.         UCASE    d1
  711.         cmp.b    d1,d0
  712.         beq.b    .STRICMP
  713.         movea.l    (LN_SUCC,a5),a5
  714.         bra.b    .LOOP
  715. .NotInList    moveq    #0,d0
  716.         bra.b    CheckIfIsInList_done
  717.  
  718. ;--------------    NEW: enable exact matching
  719. .STRCMP        move.b    (a1)+,d0
  720.         beq.b    .SEEMSTOMATCH
  721.         move.b    (a0)+,d1
  722.         cmp.b    d1,d0
  723.         beq.b    .STRCMP
  724.         movea.l    (LN_SUCC,a5),a5
  725.         bra.b    .LOOP
  726. .SEEMSTOMATCH    tst.b    (a0)+
  727.         bne.b    .LOOP
  728. .InList        moveq    #-1,d0
  729.         DONE    CheckIfIsInList
  730.  
  731. ***********************************************************************************
  732. ;--------------    show an information line about the task that called this function
  733. ;--------------    
  734.         ENTRY    ShowTaskInfo,d1-d7/a0-a6
  735.         lea    (taskinfoMsg),a1
  736.         move.l    a0,(outputArgs)
  737.         cmpi.b    #NT_PROCESS,(LN_TYPE,a0)
  738.         bne.b    .DEFAULT
  739.         tst.l    (pr_TaskNum,a0)
  740.         beq.b    .DEFAULT
  741.         move.l    (pr_CLI,a0),d0
  742.         lsl.l    #2,d0
  743.         movea.l    d0,a0
  744.         move.l    (cli_CommandName,a0),(outputArgs+4)
  745.         lea    (taskbcplMsg),a1
  746.         bra.b    .DONE
  747. .DEFAULT    move.l    (LN_NAME,a0),(outputArgs+4)
  748. .DONE        move.l    a1,a0
  749.  
  750. ;--------------    new: if SegTracker is enabled also, combine both outputs
  751.         tst.l    (SegTracker)
  752.         beq.b    .SHOWMESSAGE
  753.         move.l    (outputArgs),(st_SegTaskAddr)
  754.         move.l    (outputArgs+4),(st_SegFilename)
  755.         bra.b    ShowTaskInfo_done
  756.  
  757. .SHOWMESSAGE    jsr    ShowMessage
  758.         move.l    (window),d1
  759.         CALL    Flush,<(dosBase)>
  760.         DONE    ShowTaskInfo
  761.  
  762. ***********************************************************************************
  763. ;--------------    
  764. ;--------------    => a0: APTR address to show
  765.         ENTRY    ShowSegTracker,d0-d7/a0-a6
  766.         move.l    a0,d7                ; address to show
  767.  
  768. ;--------------    the manual says we have to do this, so we do it 
  769. ;--------------    (although we really couldn't care less, I tell you)
  770.         CALL    Forbid,<(execBase).w>
  771.  
  772. ;--------------    call SegTracker to find Hunk & Offset
  773.         movea.l    d7,a0
  774.         lea    (st_SegHunk),a1
  775.         lea    (st_SegOffset),a2
  776.         movea.l    (SegTracker),a6
  777.         jsr    a6
  778.         tst.l    d0
  779.         beq    .NOTFOUND
  780.  
  781. ;--------------    name found, copy it to our internal buffer
  782.         movea.l    d0,a0
  783.         lea    (errorMsgBuffer),a1
  784.         move.l    a1,(st_SegName)
  785.         moveq    #128-1,d0
  786. .STRCPY        move.b    (a0)+,(a1)+
  787.         beq.b    .STRCPYEND
  788.         dbra    d0,.STRCPY
  789. .STRCPYEND    move.l    d7,(st_SegAddress)
  790.  
  791. ;--------------    lets see if we can find the address
  792.         movea.l    d7,a0
  793.         lea    (st_SegList),a1
  794.         movea.l    a1,a2
  795.         movea.l    (SegTracker),a6
  796.         jsr    a6
  797.  
  798.         move.l    (st_SegList),d0
  799.         move.l    (st_SegHunk),d1
  800.         cmp.l    d0,d1
  801.         bne.b    .USESEGLIST
  802.         move.l    (st_SegOffset),d1
  803.         cmp.l    d0,d1
  804.         bne.b    .USESEGLIST
  805.         clr.l    (st_SegList)
  806. .USESEGLIST
  807. ;--------------    display the message
  808.         move.l    (window),d1
  809.         move.l    #SegTrackerMsg,d2
  810.         tst.l    (argTaskInfo)
  811.         beq.b    .NOTASKINFO
  812.         move.l    #SegTrackerMsgTI,d2
  813. .NOTASKINFO    move.l    #st_SegAddress,d3
  814.         CALL    VFPrintf,<(dosBase)>
  815.         move.l    (window),d1
  816.         CALL    Flush
  817.         bra.b    .DONE
  818.  
  819. ;--------------    show warning
  820. .NOTFOUND    tst.l    (flagSkipSegNotFound)
  821.         bne.b    .DONE
  822.         lea    (SegTrackerFail,pc),a0
  823.         jsr    ShowMessage
  824.         move.l    (window),d1
  825.         CALL    Flush,<(dosBase)>
  826. .DONE        CALL    Permit,<(execBase).w>
  827.         DONE    ShowSegTracker
  828.  
  829. ***********************************************************************************
  830. ;--------------    setup outputArgs to contain the registers as specified by 
  831. ;--------------    the register template
  832. ;--------------    
  833. ;--------------    -> a4: Patch Info
  834. ;--------------       a5: Register Data
  835. ;--------------       d0: BOOL type
  836.         ENTRY    SetupOutputData,d0-d7/a0-a6
  837.         lea    (outputArgs),a0    ; a0 = current output offset
  838.         move.w    d0,d7
  839.  
  840. ;--------------    done ? then lets go !
  841. .LOOP        move.w    (sarg_Opcode,a1),d0
  842.         cmpi.w    #REG_DONE,d0
  843.         beq    SetupOutputData_done
  844.  
  845. ;--------------    set correct register data to a2
  846.         tst.w    d7
  847.         beq.b    .DebugRegList
  848.         lea    (smsg_RegsBeforeCall,a5),a2 ; a2 = regs before call ( default )
  849.         BRBC.B    #REGB_RESULT,d0,.BeforeCall
  850.         lea    (smsg_RegsAfterCall,a5),a2 ; a2 = regs before call ( default )
  851.         bclr    #REGB_RESULT,d0
  852. .BeforeCall    bra.b    .DebugRegListDone
  853. .DebugRegList    lea    (sumsg_RegsBeforeCall,a5),a2 ; a2 = regs before call ( default )
  854.         BRBC.B    #REGB_RESULT,d0,.DebugRegListDone
  855.         lea    (sumsg_RegsAfterCall,a5),a2 ; a2 = regs before call ( default )
  856.         bclr    #REGB_RESULT,d0
  857. .DebugRegListDone
  858.  
  859.  
  860. ;--------------    use boolean tables if applicable
  861.         BRBS.B    #REGB_BOOLEAN,d0,.UseBOOLEAN
  862.  
  863. ;--------------    set correct jump table to a3
  864.         bclr    #REGB_WORD,d0
  865.         lea    (.JumpWORD,pc),a3
  866.         BRBC.B    #REGB_LONG,d0,.NotLONG
  867.         lea    (.JumpLONG,pc),a3
  868.         bclr    #REGB_LONG,d0
  869. .NotLONG    BRBC.B    #REGB_BYTE,d0,.NotBYTE
  870.         lea    (.JumpBYTE,pc),a3
  871.         bclr    #REGB_BYTE,d0
  872. .NotBYTE
  873. ;--------------    find correct table offset
  874. .ShowOutput    BRBS.B    #REGB_DATA,d0,.ISDATA
  875.         BRBC.B    #REGB_ADDR,d0,.ISADDR
  876.         lea    (8*4,a3),a3
  877.         bra.b    .ISDATA
  878. .ISADDR        BRBC.B    #REGB_INDIRECT,d0,.ISDATA
  879.         lea    (2*8*4,a3),a3
  880. .ISDATA
  881. ;--------------    now get the register data and save it
  882.         andi.w    #%111,d0
  883.         lsl.w    #2,d0
  884.         movea.l    (a3,d0.w),a3
  885.         jsr    a3
  886.         tst.w    d7
  887.         bne.b    .ITSAPATCH
  888. .ITSADEBUGMSG    lea    (2,a1),a1
  889.         bra    .LOOP
  890.  
  891. .ITSAPATCH    lea    (sarg_SIZEOF,a1),a1
  892.         bra    .LOOP
  893.  
  894. ;--------------    this isn't really 'clean code', but well it works
  895. .UseBOOLEAN    bclr    #REGB_WORD,d0
  896.         lea    (.JumpWORDBOOL,pc),a3
  897.         BRBC.B    #REGB_LONG,d0,.NotLONGBOOL
  898.         lea    (.JumpLONGBOOL,pc),a3
  899.         bclr    #REGB_LONG,d0
  900. .NotLONGBOOL    BRBC.B    #REGB_BYTE,d0,.NotBYTEBOOL
  901.         lea    (.JumpBYTEBOOL,pc),a3
  902.         bclr    #REGB_BYTE,d0
  903. .NotBYTEBOOL    bclr    #REGB_BOOLEAN,d0
  904.         bra.b    .ShowOutput
  905.  
  906.         REGLIST    LONG,L
  907.         REGLIST    WORD,W
  908.         REGLIST    BYTE,B
  909.         REGLIST    LONGBOOL,LB
  910.         REGLIST    WORDBOOL,WB
  911.         REGLIST    BYTEBOOL,BB
  912.  
  913.         SAVEREG    A0
  914.         SAVEREG    A1
  915.         SAVEREG    A2
  916.         SAVEREG    A3
  917.         SAVEREG    A4
  918.         SAVEREG    A5
  919.         SAVEREG    D0
  920.         SAVEREG    D1
  921.         SAVEREG    D2
  922.         SAVEREG    D3
  923.         SAVEREG    D4
  924.         SAVEREG    D5
  925.         SAVEREG    D6
  926.         SAVEREG    D7
  927.         SAVEREG I0
  928.         SAVEREG I1
  929.         SAVEREG I2
  930.         SAVEREG I3
  931.         SAVEREG I4
  932.         SAVEREG I5
  933.         SAVEREG I6
  934.         SAVEREG I7
  935.  
  936. .LONGBOOLEAN    move.l    #SuccessMsg,d1
  937.         tst.l    d0
  938.         bne.b    .LONGISTRUE
  939.         move.l    #FailureMsg,d1
  940. .LONGISTRUE    move.l    d1,(a0)+
  941.         rts
  942.  
  943. .WORDBOOLEAN    move.l    #SuccessMsg,d1
  944.         tst.w    d0
  945.         bne.b    .WORDISTRUE
  946.         move.l    #FailureMsg,d1
  947. .WORDISTRUE    move.l    d1,(a0)+
  948.         rts
  949.  
  950.         DONE    SetupOutputData
  951.  
  952. ***********************************************************************************
  953. ;--------------    patch all functions in the watch list
  954. ;--------------    
  955.         ENTRY    PatchFunctions,d1-d7/a0-a6
  956.  
  957. ;--------------    1.PASS: patch all library functions
  958.         lea    (watches),a5
  959.         movea.l    (LH_HEAD,a5),a5
  960.         movea.l    (execBase).w,a6
  961. .LOOPPASS1    tst.l    (LN_SUCC,a5)    ; a5 = current node
  962.         beq.b    .DONEPASS1
  963.         movea.l    a5,a0
  964.         bsr.b    InstallPatch
  965.         tst    d0
  966.         beq.b    .LIBFAILED
  967.         movea.l    (LN_SUCC,a5),a5
  968.         bra.b    .LOOPPASS1
  969.  
  970. ;--------------    2.PASS: patch all device functions
  971. .DONEPASS1    lea    (deviceBases),a5
  972.         movea.l    (LH_HEAD,a5),a5
  973.         movea.l    (execBase).w,a6
  974. .LOOPPASS2    tst.l    (LN_SUCC,a5)    ; a5 = current node
  975.         beq.b    .DONEPASS2
  976.  
  977. ;--------------    patch BeginIO()
  978.         movea.l    a5,a0
  979.         lea    (BeginIO_Patch),a1
  980.         lea    (BeginIO_Jump),a2
  981.         move.l    (BeginIO_SIZEOF),d0
  982.         move.w    #DEV_BEGINIO,d1
  983.         bsr    InstallDevicesPatch
  984.         tst    d0
  985.         beq.b    .DEVFAILED
  986.  
  987. ;--------------    patch AbortIO()
  988.         movea.l    a5,a0
  989.         lea    (AbortIO_Patch),a1
  990.         lea    (AbortIO_Jump),a2
  991.         move.l    (AbortIO_SIZEOF),d0
  992.         move.w    #DEV_ABORTIO,d1
  993.         bsr    InstallDevicesPatch
  994.         tst    d0
  995.         beq.b    .DEVFAILED
  996.  
  997.         movea.l    (LN_SUCC,a5),a5
  998.         bra.b    .LOOPPASS2
  999. .DONEPASS2    moveq    #TRUE,d0
  1000.         bra.b    PatchFunctions_done
  1001.  
  1002. .DEVFAILED    clr.l    (sdevbase_IOSize,a5)
  1003.         moveq    #FALSE,d0
  1004.         bra.b    PatchFunctions_done
  1005.  
  1006. .LIBFAILED    clr.l    (spatch_Library,a5) ; to indicate failed patch
  1007.         moveq    #FALSE,d0
  1008.         DONE    PatchFunctions
  1009.  
  1010. ***********************************************************************************
  1011. ;--------------    Patch a system function
  1012. ;-------------- 
  1013. ;--------------    => a0: APTR Patchinfo 
  1014. ;--------------    <= d0: LONG success
  1015. ;--------------    
  1016.         ENTRY    InstallPatch,d1-d7/a0-a6
  1017.         movea.l    a0,a5
  1018.         move.l    a0,(PatchInfoStruct)
  1019.  
  1020. ;--------------    allocate patch duplicate
  1021.         move.l    (Patch_SIZEOF),d0
  1022.         move.l    #MEMF_PUBLIC|MEMF_CLEAR,d1
  1023.         CALL    AllocMem,<(execBase).w>
  1024.         tst.l    d0
  1025.         beq.b    .FAIL
  1026.         movea.l    d0,a4
  1027.  
  1028. ;--------------    setup original vector
  1029.         movea.l    (spatch_Library,a5),a1
  1030.         move.w    (spatch_Offset,a5),d1
  1031.         addq.w    #2,d1
  1032.         move.l    (a1,d1.w),(OriginalVector0+2)
  1033.         move.l    (a1,d1.w),(OriginalVector1+2)
  1034.         move.l    (a1,d1.w),(Patch_START+sphead_OriginalFunction)
  1035.  
  1036. ;--------------    this is VERY important because otherwise Snoopy couldn't
  1037. ;--------------    handle multiple instances so well 
  1038.         move.l    (ThisTask,a6),(Patch_START+sphead_Owner)
  1039.  
  1040. ;--------------    copy patch memory
  1041.         movea.l    a4,a0
  1042.         lea    (Patch_START),a1
  1043.         move.l    (Patch_SIZEOF),d0
  1044.         subq.w    #1,d0
  1045. .LOOP        move.b    (a1)+,(a0)+
  1046.         dbra    d0,.LOOP
  1047.  
  1048. ;--------------    install new function
  1049.         movea.l    (spatch_Library,a5),a1
  1050.         move.w    (spatch_Offset,a5),d0
  1051.         ext.l    d0
  1052.         movea.l    d0,a0
  1053.         move.l    a4,d0
  1054.         addi.l    #sphead_SIZEOF,d0
  1055.         CALL    SetFunction
  1056.         
  1057. .SUCCESS    moveq    #TRUE,d0
  1058.         bra.b    InstallPatch_done
  1059.         
  1060. .FAIL        moveq    #FALSE,d0
  1061.         DONE    InstallPatch
  1062.  
  1063. ***********************************************************************************
  1064. ;--------------    Patch a system function
  1065. ;-------------- 
  1066. ;--------------    => a0: APTR Patchinfo 
  1067. ;--------------    <= d0: LONG success
  1068. ;--------------    
  1069.         STRUCTURE idpStack,0
  1070.         APTR    idps_DeviceBase
  1071.         APTR    idps_BeginOfPatch
  1072.         APTR    idps_JumpAddress
  1073.         APTR    idps_SizeOfPatch
  1074.         WORD    idps_Offset
  1075.         LABEL    idps_SIZEOF
  1076.  
  1077.         ENTRY    InstallDevicesPatch,d1-d7/a0-a6,idps_SIZEOF,a5
  1078.         move.l    a0,(idps_DeviceBase,a5)
  1079.         move.l    a1,(idps_BeginOfPatch,a5)
  1080.         move.l    a2,(idps_JumpAddress,a5)
  1081.         move.l    d0,(idps_SizeOfPatch,a5)
  1082.         move.w    d1,(idps_Offset,a5)
  1083.  
  1084. ;--------------    allocate patch duplicate
  1085.         move.l    (idps_SizeOfPatch,a5),d0
  1086.         move.l    #MEMF_PUBLIC|MEMF_CLEAR,d1
  1087.         CALL    AllocMem,<(execBase).w>
  1088.         tst.l    d0
  1089.         beq.b    .FAIL
  1090.         movea.l    d0,a4            ; a4 = patch memory
  1091.  
  1092. ;--------------    setup original vector
  1093.         movea.l    (idps_DeviceBase,a5),a3    ; a3 = (SnoopyDeviceBase *)
  1094.         movea.l    (sdevbase_Device,a3),a1    ; a1 = (struct Device *)
  1095.         move.w    (idps_Offset,a5),d1    ; d1 = (function offset)
  1096.         addq.w    #2,d1    
  1097.         movea.l    (idps_JumpAddress,a5),a0
  1098.         move.l    (a1,d1.w),(2,a0)    ; set jump address
  1099.         movea.l    (idps_BeginOfPatch,a5),a0
  1100.         move.l    (a1,d1.w),(sphead_OriginalFunction,a0)
  1101.         move.l    (sdevbase_IOSize,a3),(sphead_Info,a0)
  1102.         move.l    a3,(sphead_DevicePtr,a0)
  1103.  
  1104. ;--------------    copy patch memory
  1105.         movea.l    a4,a0
  1106.         movea.l    (idps_BeginOfPatch,a5),a1
  1107.         move.l    (ThisTask,a6),(sphead_Owner,a1)
  1108.         move.l    (idps_SizeOfPatch,a5),d0
  1109.         subq.w    #1,d0
  1110. .LOOP        move.b    (a1)+,(a0)+
  1111.         dbra    d0,.LOOP
  1112.  
  1113. ;--------------    install new function
  1114.         movea.l    (sdevbase_Device,a3),a1
  1115.         move.w    (idps_Offset,a5),d0
  1116.         ext.l    d0
  1117.         movea.l    d0,a0
  1118.         move.l    a4,d0
  1119.         addi.l    #sphead_ExtSIZEOF,d0
  1120.         CALL    SetFunction
  1121. .SUCCESS    moveq    #TRUE,d0
  1122.         bra.b    InstallDevicesPatch_done
  1123.         
  1124. .FAIL        moveq    #FALSE,d0
  1125.         DONE    InstallDevicesPatch
  1126.  
  1127. ***********************************************************************************
  1128. ;--------------    remove the patch of all functions in the watch list
  1129. ;--------------    
  1130.         ENTRY    RemoveFunctions,d1-d7/a0-a6
  1131.         lea    (watches),a5
  1132.         movea.l    (LH_HEAD,a5),a5
  1133.         movea.l    (execBase).w,a6
  1134. .LOOP1        tst.l    (LN_SUCC,a5)    ; a5 = current node
  1135.         beq.b    .DONE1
  1136.         movea.l    a5,a0
  1137.         bsr    RemovePatch
  1138.         tst.w    d0
  1139.         beq.b    .FAILURE
  1140.         movea.l    (LN_SUCC,a5),a5
  1141.         bra.b    .LOOP1
  1142. .DONE1
  1143.         lea    (deviceBases),a5
  1144.         movea.l    (LH_HEAD,a5),a5
  1145. .LOOP2        tst.l    (LN_SUCC,a5)    ; a5 = current node
  1146.         beq.b    .DONE2
  1147.         movea.l    a5,a0
  1148.  
  1149. ;--------------    unpatch BeginIO()
  1150.         movea.l    a5,a0
  1151.         lea    (BeginIO_Patch),a1
  1152.         lea    (BeginIO_Jump),a2
  1153.         move.l    (BeginIO_SIZEOF),d0
  1154.         move.w    #DEV_BEGINIO,d1
  1155.         bsr    RemoveDevicePatch
  1156.         tst    d0
  1157.         beq.b    .BEGINIOERR
  1158.  
  1159. ;--------------    unpatch AbortIO()
  1160.         movea.l    a5,a0
  1161.         lea    (AbortIO_Patch),a1
  1162.         lea    (AbortIO_Jump),a2
  1163.         move.l    (AbortIO_SIZEOF),d0
  1164.         move.w    #DEV_ABORTIO,d1
  1165.         bsr    RemoveDevicePatch
  1166.         tst    d0
  1167.         beq.b    .ABORTIOERR
  1168.  
  1169.         movea.l    (LN_SUCC,a5),a5
  1170.         bra.b    .LOOP2
  1171. .DONE2        moveq    #TRUE,d0
  1172.         bra.b    RemoveFunctions_done
  1173.  
  1174. ;--------------    error in DEV_BEGINIO()
  1175. .BEGINIOERR    move.l    #closeBeginIoErr,d2
  1176.         bra.b    .DEVICEERROR
  1177.  
  1178. ;--------------    error in DEV_ABORTIO()
  1179. .ABORTIOERR    move.l    #closeAbortIoErr,d2
  1180. .DEVICEERROR    movea.l    (sdevbase_Device,a5),a1
  1181.         movea.l    (LN_NAME,a1),a1
  1182.         bra.b    .SHOWERRORMSG
  1183.  
  1184. ;--------------    show error messages
  1185. .FAILURE    lea    (spatch_Template,a5),a1
  1186.         move.l    #closesnoopyErr,d2
  1187. .SHOWERRORMSG    move.l    a1,(outputArgs)
  1188.         move.l    (window),d1
  1189.         move.l    #outputArgs,d3
  1190.         CALL    VFPrintf,<(dosBase)>
  1191.         move.l    (window),d1
  1192.         CALL    Flush
  1193.         moveq    #FALSE,d0
  1194.         DONE    RemoveFunctions
  1195.  
  1196. ***********************************************************************************
  1197. ;--------------    Remove patch of a system function
  1198. ;-------------- 
  1199. ;--------------    => a0: APTR Patchinfo 
  1200. ;--------------    
  1201.         ENTRY    RemovePatch,d1-d7/a0-a3/a5/a6
  1202.         movea.l    a0,a5
  1203.  
  1204. ;--------------    test if it is our patch
  1205.         tst.l    (spatch_Library,a5)
  1206.         beq    .SUCCESS
  1207.         movea.l    (spatch_Library,a5),a1
  1208.         move.w    (spatch_Offset,a5),d1
  1209.         addq.w    #2,d1
  1210.         move.l    (a1,d1.w),a1
  1211.         subi.l    #sphead_SIZEOF,a1
  1212.         cmpi.l    #PATCH_IDSTRING,(sphead_Ident,a1)
  1213.         bne.b    .REMOVEFAILED
  1214.         movea.l    (execBase).w,a6
  1215.         move.l    (ThisTask,a6),d0
  1216.         cmp.l    (sphead_Owner,a1),d0
  1217.         bne.b    .REMOVEFAILED
  1218.         movea.l    a1,a4            ; a4 = patched memory
  1219.         tst.l    (sphead_OriginalFunction,a4)
  1220.         beq.b    .SUCCESS
  1221.  
  1222. ;--------------    restore original function
  1223.         movea.l    (spatch_Library,a5),a1
  1224.         move.w    (spatch_Offset,a5),d0
  1225.         ext.l    d0
  1226.         movea.l    d0,a0
  1227.         move.l    (sphead_OriginalFunction,a4),d0
  1228.         CALL    SetFunction,<(execBase).w>
  1229.         clr.l    (sphead_OriginalFunction,a4)
  1230.  
  1231. ;--------------    free patched memory
  1232.         movea.l    a4,a1
  1233.         move.l    (Patch_SIZEOF),d0
  1234.         CALL    FreeMem
  1235.         
  1236. .SUCCESS    moveq    #TRUE,d0
  1237.         bra.b    RemovePatch_done
  1238.  
  1239. ;--------------    
  1240. .REMOVEFAILED    moveq    #FALSE,d0
  1241.         DONE    RemovePatch
  1242.  
  1243. ***********************************************************************************
  1244. ;--------------    Remove patch of a system device
  1245. ;-------------- 
  1246. ;--------------    => a0: SnoopyDeviceBase *
  1247. ;--------------    
  1248.         ENTRY    RemoveDevicePatch,d1-d7/a0-a6,idps_SIZEOF,a5
  1249.         move.l    a0,(idps_DeviceBase,a5)
  1250.         move.l    a1,(idps_BeginOfPatch,a5)
  1251.         move.l    a2,(idps_JumpAddress,a5)
  1252.         move.l    d0,(idps_SizeOfPatch,a5)
  1253.         move.w    d1,(idps_Offset,a5)
  1254.  
  1255. ;--------------    test if it is our patch
  1256.         movea.l    (idps_DeviceBase,a5),a3    ; a3 = SnoopyDeviceBase *
  1257.         movea.l    (sdevbase_Device,a3),a1
  1258.         move.w    (idps_Offset,a5),d1
  1259.         addq.w    #2,d1
  1260.         movea.l    (a1,d1.w),a1
  1261.         suba.l    #sphead_ExtSIZEOF,a1
  1262.         cmpi.l    #PATCH_IDSTRING,(sphead_Ident,a1)
  1263.         bne.b    .REMOVEFAILED
  1264.         movea.l    (execBase).w,a6
  1265.         move.l    (ThisTask,a6),d0
  1266.         cmp.l    (sphead_Owner,a1),d0
  1267.         bne.b    .REMOVEFAILED
  1268.         move.l    a1,a4            ; a4 = patched memory
  1269.         tst.l    (sphead_OriginalFunction,a4)
  1270.         beq.b    .SUCCESS
  1271.  
  1272. ;--------------    restore original function
  1273.         movea.l    (sdevbase_Device,a3),a1
  1274.         move.w    (idps_Offset,a5),d0
  1275.         ext.l    d0
  1276.         movea.l    d0,a0
  1277.         move.l    (sphead_OriginalFunction,a4),d0
  1278.         CALL    SetFunction,<(execBase).w>
  1279.         clr.l    (sphead_OriginalFunction,a4)
  1280.  
  1281. ;--------------    free patched memory
  1282.         movea.l    a4,a1
  1283.         move.l    (idps_SizeOfPatch,a5),d0
  1284.         CALL    FreeMem
  1285.         
  1286. .SUCCESS    moveq    #TRUE,d0
  1287.         bra.b    RemoveDevicePatch_done
  1288.  
  1289. ;--------------    
  1290. .REMOVEFAILED    moveq    #FALSE,d0
  1291.         DONE    RemoveDevicePatch
  1292.  
  1293. ***********************************************************************************
  1294. ;--------------    remove any running instance of Snoopy
  1295. ;--------------    
  1296.         ENTRY    QuitSnoopyInstances,d0-d7/a0-a6
  1297.  
  1298. ;--------------    d7 = Instance Number; if d7 == 0, remove ALL instances,
  1299. ;--------------    else remove only the numbered instance
  1300.         movea.l    (argQuit),a0
  1301.         move.l    (a0),d7
  1302.         beq    .REMOVEALL
  1303.  
  1304. ;--------------    stop fooling around
  1305.         CALL    Forbid,<(execBase).w>
  1306.  
  1307. ;--------------    examine waiting tasks
  1308.         lea    (TaskWait,a6),a4
  1309.         movea.l    (LH_HEAD,a4),a4
  1310. .LOOP1        tst.l    (LN_SUCC,a4)
  1311.         beq.b    .DONE1
  1312.         bsr.b    .FINDSNOOPY
  1313.         bsr.b    .REMTASK
  1314.         movea.l    (LN_SUCC,a4),a4
  1315.         bra.b    .LOOP1
  1316.  
  1317. ;--------------    examine ready tasks
  1318. .DONE1        lea    (TaskReady,a6),a4
  1319.         movea.l    (LH_HEAD,a4),a4
  1320. .LOOP2        tst.l    (LN_SUCC,a4)
  1321.         beq.b    .DONE2
  1322.         bsr.b    .FINDSNOOPY
  1323.         bsr.b    .REMTASK
  1324.         movea.l    (LN_SUCC,a4),a4
  1325.         bra.b    .LOOP2
  1326. .DONE2        CALL    Permit
  1327.         bra    QuitSnoopyInstances_done
  1328.  
  1329. ;--------------    remove task if it fits 
  1330. .REMTASK    tst.w    d1
  1331.         beq.b    .FAILREMTASK
  1332.         cmp.w    d7,d1
  1333.         bne.b    .FAILREMTASK
  1334.          movea.l    a4,a1
  1335.         move.l    #SIGBREAKF_CTRL_C,d0
  1336.         CALL    Signal
  1337. .FAILREMTASK    rts
  1338.  
  1339. ;--------------    trys to find out the name for a task
  1340. ;--------------    
  1341. ;--------------    <= d0:BOOL success
  1342. ;--------------       d1:LONG instance number of the task currently found
  1343. .FINDSNOOPY    movea.l    (LN_NAME,a4),a0
  1344.         lea    (taskNameFormat,pc),a1
  1345.         moveq    #taskNameFormat_SIZEOF-1,d0
  1346. .STRCMP        move.b    (a0)+,d1
  1347.         cmp.b    (a1)+,d1
  1348.         bne.b    .SKIP
  1349.         dbra    d0,.STRCMP
  1350.         moveq    #STVFORMAT_DEC,d0
  1351.         jsr    StringToValue
  1352.         move.l    d0,d1
  1353.         moveq    #TRUE,d0
  1354.         rts
  1355. .SKIP        moveq    #FALSE,d0
  1356.         rts
  1357.  
  1358. MAX_ACTIVESNOOPYS    equ    MAX_INPUT
  1359.  
  1360. ;--------------    find all active snoopy numbers and store them in InputMemory[]
  1361. .REMOVEALL    lea    (inputMemory),a3
  1362.         CALL    Forbid,<(execBase).w>
  1363.         lea    (TaskWait,a6),a4
  1364.         bsr.b    .FINDSNOOPYS
  1365.         lea    (TaskReady,a6),a4
  1366.         bsr.b    .FINDSNOOPYS
  1367.         CALL    Permit
  1368.  
  1369. ;--------------    now of course I could be write a quicksort algorithm, but
  1370. ;--------------    really the following method is easier: I just try to find
  1371. ;--------------    the maximum element, break it, then start the loop again
  1372.         move.l    a3,d7
  1373.         subi.l    #inputMemory+1,d7
  1374. .ra_Loop    move.l    d7,d2        ; loop counter
  1375.         lea    (inputMemory),a3
  1376.         moveq    #0,d0        ; current maximum
  1377. .ra_FindMax    move.b    (a3),d1
  1378.         cmp.b    d1,d0
  1379.         bge.b    .ra_NotMax
  1380.         move.b    d1,d0
  1381.         move.l    a3,a2
  1382. .ra_NotMax    addq.l    #1,a3
  1383.         dbra    d2,.ra_FindMax
  1384.         tst    d0
  1385.         beq.b    QuitSnoopyInstances_done
  1386.         clr.b    (a2)
  1387.  
  1388. ;--------------    clear this element
  1389.         lea    (outputArgs),a1        
  1390.         move.l    d0,(a1)
  1391.         lea    (taskNameFormat,pc),a0
  1392.         lea    (currentTaskName),a2
  1393.         jsr    SPrintf
  1394.         lea    (currentTaskName),a1
  1395.         CALL    FindTask
  1396.         tst.l    d0
  1397.         beq.b    .ra_Loop
  1398.          movea.l    d0,a1
  1399.         move.l    #SIGBREAKF_CTRL_C,d0
  1400.         CALL    Signal
  1401.         bra.b    .ra_Loop
  1402.  
  1403. .FINDSNOOPYS    movea.l    (LH_HEAD,a4),a4
  1404. .fs_LOOP    tst.l    (LN_SUCC,a4)
  1405.         beq.b    .fs_DONE
  1406.         bsr    .FINDSNOOPY
  1407.         tst.b    d0
  1408.         beq.b    .fs_SKIP
  1409.         move.b    d1,(a3)+
  1410. .fs_SKIP    movea.l    (LN_SUCC,a4),a4
  1411.         bra.b    .fs_LOOP
  1412. .fs_DONE    rts
  1413.  
  1414.         DONE    QuitSnoopyInstances
  1415.         
  1416. ***********************************************************************************
  1417. ;--------------    note: I use some very old code here stolen from a program I wrote
  1418. ;--------------    some year ago together with a friend of mine (Stefan Scherer);
  1419. ;--------------    this code isn't well documented but it works just fine so why bother....
  1420.         ENTRY    ReadWBArgs,d0-d7/a0-a6
  1421.          lea    (TTHStruktur),a3
  1422.         move.l    (tth_WBStartup,a3),d0
  1423.         beq    ReadWBArgs_done
  1424.         tst.l    (argRdargs)
  1425.         bne    ReadWBArgs_done
  1426.         clr.l    (argRdargs)
  1427.  
  1428. ;--------------    normal startup from workbench
  1429. .vonWorkbench    movea.l    d0,a3
  1430.         move.l    (sm_NumArgs,a3),d0
  1431.         movea.l    (sm_ArgList,a3),a3
  1432.         cmpi.l    #1,d0
  1433.         beq.b    .DEFSTART
  1434.         lea    (wa_SIZEOF,a3),a3
  1435.  
  1436. .DEFSTART    move.l    (wa_Lock,a3),d1            ; DirLock zeigt auf
  1437.         CALL    CurrentDir,<(dosBase)>        ; Pfad des Programms
  1438.         move.l    (wa_Name,a3),a0
  1439. .LeseIcon    CALL    GetDiskObject,<(iconBase)>    ; ".info"-Datei lesen
  1440.         BRF    d0,ReadWBArgs_done        ; Fehler, dann weiter
  1441.  
  1442. ;--------------    Tool Types auswerten
  1443.         move.l    d0,a3
  1444.         cmpi.b    #WBPROJECT,(do_PAD_BYTE-1,a3)
  1445.         beq    .USEPROJECT
  1446.         move.l    (do_ToolTypes,a3),a3    
  1447.         move.l    a3,a0
  1448.         lea    (TTScript,pc),a1
  1449.         push    a0
  1450.         CALL    FindToolType
  1451.         pop    a0
  1452.         move.l    d0,(argScript)
  1453.  
  1454. .READTOOLTYPES    movea.l    a0,a5
  1455.         lea    (TTIncdir,pc),a1
  1456.         movea.l    a5,a0
  1457.         CALL    FindToolType
  1458.         move.l    d0,(argIncdir)
  1459.         lea    (TTOutput,pc),a1
  1460.         movea.l    a5,a0
  1461.         CALL    FindToolType
  1462.         move.l    d0,(argOutput)
  1463.         lea    (TTPri,pc),a1
  1464.         movea.l    a5,a0
  1465.         CALL    FindToolType
  1466.         tst.l    d0
  1467.         beq.b    .SKIPPRI
  1468.         movea.l    d0,a0
  1469.         moveq    #STVFORMAT_DEC,d0
  1470.         jsr    StringToValue
  1471.         move.l    d0,(priority)
  1472. .SKIPPRI    lea    (TTSticky,pc),a1
  1473.         lea    (argSticky),a2
  1474.         bsr.b    .GETBOOLEAN
  1475.         lea    (TTNoSegTracker,pc),a1
  1476.         lea    (argNoSegTracker),a2
  1477.         bsr.b    .GETBOOLEAN
  1478.         lea    (TTMatch,pc),a1
  1479.         lea    (argMatch),a2
  1480.         bsr.b    .GETBOOLEAN
  1481.         lea    (TTTaskInfo,pc),a1
  1482.         lea    (argTaskInfo),a2
  1483.         bsr.b    .GETBOOLEAN
  1484.         bra.b    ReadWBArgs_done
  1485.  
  1486. .GETBOOLEAN    movea.l    a5,a0
  1487.         push    a2
  1488.         CALL    FindToolType
  1489.         pop    a1
  1490.         tst.l    d0
  1491.         beq.b    .ISNTBOOL
  1492.         movea.l    d0,a0
  1493.         jsr    FindBooleanKeyword
  1494. .ISNTBOOL    rts
  1495.  
  1496. .USEPROJECT    push    a3
  1497.         lea    (TTHStruktur),a3
  1498.         move.l    (tth_WBStartup,a3),a3
  1499.         move.l    (sm_ArgList,a3),a3
  1500.         lea    (wa_SIZEOF,a3),a3
  1501.         move.l    (wa_Name,a3),(argScript)
  1502.         pop    a3
  1503.         move.l    (do_ToolTypes,a3),a3    
  1504.         move.l    a3,a0
  1505.         bra    .READTOOLTYPES
  1506.         DONE    ReadWBArgs
  1507.  
  1508. ***********************************************************************************
  1509.  
  1510.         cstr    "$VER: ",IDSTRING
  1511.  
  1512. ;--------------    library definitions
  1513. dosName        cstr    "dos.library"
  1514. intName        cstr    "intuition.library"
  1515. iconName    cstr    "icon.library"
  1516.  
  1517. ;--------------    global text messages
  1518. defaultScript    cstr    DEFAULTSCRIPT
  1519. TIenabledMsg    cstr    'TaskInfo enabled\n'
  1520. TIdisabledMsg    cstr    'TaskInfo disabled\n'
  1521. taskinfoMsg    cstr    'Task %08lx : "%s"\n'
  1522. taskbcplMsg    cstr    'Task %08lx : "%b"\n'
  1523. helloMsg    cstr    "Welcome to ",IDSTRING,"[%ld] - written by ",AUTHORSTRING,"\n"
  1524. disableoutMsg    cstr    "Output disabled - press CTRL+E to enable again. \n"
  1525. enableoutMsg    cstr    "Output enabled - press CTRL+D to disable. \n"
  1526. windowName    cstr    "con:0/0/640/150/",IDSTRING
  1527.  
  1528. ;--------------    template for dos/ReadArgs()
  1529. argTemplate    dc.b    "SCRIPT,"
  1530.         dc.b    "TASKINFO/S,"
  1531.         dc.b    "OUTPUT/K,"
  1532.         dc.b    "PRI/N,"
  1533.         dc.b    "SHOW/K/M,"
  1534.         dc.b    "STICKY/S,"
  1535.         dc.b    "MATCH/S,"
  1536.         dc.b    "QUIT/K/N,"
  1537.         dc.b    "INCDIR/K,"
  1538.         dc.b    "NOSEGTRACKER/S"
  1539.         dc.b    0
  1540.  
  1541. ;--------------    workbench tooltypes
  1542. TTScript    cstr    "SCRIPT"
  1543. TTPri        cstr    "PRI"
  1544. TTOutput    cstr    "OUTPUT"
  1545. TTSticky    cstr    "STICKY"
  1546. TTNoSegTracker    cstr    "NOSEGTRACKER"
  1547. TTTaskInfo    cstr    "TASKINFO"
  1548. TTMatch        cstr    "MATCH"
  1549. TTIncdir    cstr    "INCDIR"
  1550.  
  1551. ;--------------    name of SegTracker semaphore
  1552. SegTrackerName    cstr    "SegTracker"
  1553. SegTrackerMsg    cstr    "$%08lx - %s : Hunk %ld, Offset $%08lx, SegList $%08lx\n"
  1554. SegTrackerMsgTI    cstr    'PC=$%lx,N="%s",H=%ld,O=$%lx,S=$%lx,A=%lx,T="%s"\n'
  1555. SegTrackerFail    cstr    "(Segment not found)\n"
  1556. SegTrackerOn    dc.b    FALSE
  1557.  
  1558. ;--------------    error messages for this module
  1559. nowindowErr    cstr    "ERROR, cannot open output stream"
  1560. nomsgportErr    cstr    "ERROR, cannot create msgport"
  1561. closesnoopyErr    dc.b    10,'*** WARNING *** Something else has patched the vectors Snoopy looks into'
  1562.         dc.b    10,'You will have to wait for the other program to finish and try Snoopy again'
  1563.         dc.b    10,'The function I have trouble with is the one with the template'
  1564.         dc.b    10,'"%s"',10,0
  1565. closeBeginIoErr    cstr    "ERROR, cannot remove DEV_BEGINIO() for %s\n",0
  1566. closeAbortIoErr    cstr    "ERROR, cannot remove DEV_ABORTIO() for %s\n",0
  1567. activeCallsErr    cstr    "ERROR, %ld calls still working",0
  1568. newlineMsg    cstr    '\n'
  1569.  
  1570. ;--------------    new: flexible naming schedule
  1571. taskNameFormat    dc.b    "Snoopy Task."
  1572. taskNameFormat_SIZEOF    equ    *-taskNameFormat
  1573.         cstr    "%ld",0
  1574. taskPortFormat    cstr    "Snoopy Port.%ld",0
  1575.  
  1576. ;--------------    success/failure messages
  1577. SuccessMsg    cstr    "YES"
  1578. FailureMsg    cstr    "NO"
  1579.  
  1580. ;--------------    internal messages : not documented (try to find out yourself....)
  1581. abortIOMsg    cstr    "AbortIO"
  1582. beginIOMsg    cstr    "BeginIO"
  1583.  
  1584. ;--------------    user messages
  1585. DebugDefTempMsg    dc.b    "**** Userfunction before call *********************************************",10
  1586.         dc.b    "Dx:%08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx",10
  1587.         dc.b    "Ax:%08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx",10
  1588.         dc.b    "():%08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx",10
  1589.         dc.b    "**** Userfunction after call",10
  1590.         dc.b    "Dx:%08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx",10
  1591.         dc.b    "Ax:%08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx",10
  1592.         dc.b    "():%08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx",10,0
  1593.  
  1594.         section    memory,bss
  1595.         
  1596. ;--------------    library bases (guess what)
  1597.         defs.l    dosBase,1
  1598.         defs.l    intBase,1
  1599.         defs.l    iconBase,1
  1600.  
  1601. ;--------------    all internal lists
  1602.         defs.b    hides,LH_SIZE
  1603.         defs.b    shows,LH_SIZE
  1604.         defs.b    bases,LH_SIZE
  1605.         defs.b    watches,LH_SIZE
  1606.         defs.b    deviceBases,LH_SIZE
  1607.         defs.b    aliases,LH_SIZE
  1608.         defs.b    defines,LH_SIZE
  1609.         defs.b    resources,LH_SIZE
  1610.  
  1611. ;--------------    other global data
  1612.         defs.l    SegTracker,1    ; SegTracker semaphore or NULL if it doesn't exist
  1613.         defs.l    myport,1    ; port where all Snoopy messages arrive
  1614.         defs.l    window,1    ; pointer to current output channel
  1615.         defs.l    thistask,1    ; pointer to my own task
  1616.         defs.l    ActiveCalls,1    ; counts the number of active calls
  1617.  
  1618. ;--------------    internal data (locally used only within this module)
  1619. answersignal    ds.l    1    ; the signalmask used for SendMsg()/GetMsg() answers
  1620. waitsignals    ds.l    1    ; signals to Wait() for
  1621. message        ds.l    1    ; last message recieved by GetMsg()
  1622. signals        ds.l    1    ; signals actually recieved by Wait()
  1623. lastMessage    ds.l    1    ; pointer to last message (for SKIPSIMILAR)
  1624.  
  1625. ;--------------    stuff for ReadArgs
  1626. argRdargs    ds.l    1    ; for allocated memory (dos.library INTERNALs)
  1627. argFirst    
  1628.         defs.l    argScript,1    ; name of scriptfile or NULL for defaults
  1629.         defs.l    argTaskInfo,1    ; TRUE if extended task info is to be given
  1630.         defs.l    argOutput,1    ; name of redirected filename or NULL for the window
  1631.         defs.l    argPri,1    ; priority number or NULL
  1632.         defs.l    argShow,1     ; array of tasknames to show or NULL
  1633.         defs.l    argSticky,1    ; KEEP STICKY
  1634.         defs.l    argMatch,1    ; use exact matching
  1635.         defs.l    argQuit,1    ; remove snoopy instances
  1636.         defs.l    argIncdir,1
  1637.         defs.l    argNoSegTracker,1
  1638. outputactive    ds.b    1
  1639.         defs.b    showsactive,1
  1640.  
  1641. ;--------------    contains the actual task/port names made by BuildSnoopysTaskname()
  1642. currentTaskName    ds.b    40
  1643. currentPortName    ds.b    40
  1644. currentInstance    ds.l    1    ; instance counter
  1645.  
  1646. ;--------------    segtracker output data
  1647. st_SegAddress    ds.l    1
  1648. st_SegName    ds.l    1
  1649. st_SegHunk    ds.l    1
  1650. st_SegOffset    ds.l    1
  1651. st_SegList    ds.l    1
  1652. st_SegTaskAddr    ds.l    1
  1653. st_SegFilename    ds.l    1
  1654. errorMsgBuffer    ds.b    256
  1655.  
  1656. ***********************************************************************************
  1657. ;--------------    
  1658.